package org.example.originUtils

import org.apache.commons.collections.MapUtils
import org.apache.commons.lang3.StringUtils
import org.apache.commons.lang3.time.FastDateFormat
import org.example.common.Logging
import org.example.constant.RiskConst
import org.example.dao.{AlarmEvidence, AlarmNumber}
import org.example.logic.PeriodProcess
import org.example.model.MapToJson
import org.example.utils.{CommonUtils, RedisSink}
import org.example.utils.SearchInfo.mysqlConn
import org.joda.time.format.DateTimeFormat
import org.joda.time.{DateTime, Minutes}

import java.sql.{Connection, PreparedStatement, ResultSet}
import java.util
import scala.collection.JavaConverters._
import scala.collection.mutable.ListBuffer

object EquipmentAlarmProduce extends Logging {
  /**
   * GPS设备上线异常和智能设备上线异常处理
   *
   * @param key
   * @param dateTime
   * @param smartDatas
   * @param gpsDatas
   * @param baseWarn
   * @param warnCode
   * @param jedis
   * @param warnList
   * @param riskTimeList
   */
  def onlineAbnormalAlarm(key: String,
                          dateTime: String,
                          smartDatas: util.Map[String, String],
                          gpsDatas: util.Map[String, String],
                          baseWarn: Map[String, String],
                          warnCode: String,
                          jedis: RedisSink,
                          warnList: ListBuffer[(String, String)],
                          riskTimeList: ListBuffer[AlarmNumber]): Unit = {
    val formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
    val format = FastDateFormat.getInstance("yyyyMMdd")
    //    //
    //    val vehScheduleInfo: util.HashMap[String, String] = getVehScheduleInfo()
    //检测时间
    val detectionTime = DateTime.parse(dateTime, formatter)
    //风险触发时间
    val riskMillis = detectionTime.getMillis
    val warnDay = format.format(riskMillis)
    if (MapUtils.isNotEmpty(smartDatas)) {
      //更新的信息
      val resultMap = new util.HashMap[String, String]()
      //报警list
      val smartMap = smartDatas.asScala.map { x =>
        val splits = x._2.split("\\|")
        var minutes = 0
        try {
          val lastOnlineSmartTime = DateTime.parse(splits(0), formatter)
          //智能设备最后上线时间和当前检测时间差
          minutes = Minutes.minutesBetween(lastOnlineSmartTime, detectionTime).getMinutes
        } catch {
          case e: Exception => {
            error(s"设备最后上线时间格式不对:${splits(0)}")
          }
        }

        var equipmentWarnMinutes = 0
        if (2 == splits.size) {
          val lastWarnTimeDay = DateTime.parse(splits(1), formatter)
          equipmentWarnMinutes = Minutes.minutesBetween(lastWarnTimeDay, detectionTime).getMinutes
        }

        var equipmentWarnType = 0
        //智能设备异常报警
        if ((minutes >= 1440 && equipmentWarnMinutes == 0) || equipmentWarnMinutes >= 1440) {
          //判断是否有定位数据
          val gpsData = gpsDatas.get(x._1)
          //          val schedulingState: String = vehScheduleInfo.getOrDefault(x._1,"")
          if (StringUtils.isNotEmpty(gpsData)) {
            val gpsDateTime = gpsData.split("\\|")
            val gpsTime = DateTime.parse(gpsDateTime(0), formatter)
            val gpsMinutes = Minutes.minutesBetween(gpsTime, detectionTime).getMinutes
            if (gpsMinutes < 1440) {
              //              //加入判断车辆排班信息
              //              if(schedulingState.isEmpty || schedulingState == 1 || schedulingState == -1){
              equipmentWarnType = 1
              resultMap.put(x._1, splits(0) + "|" + dateTime)
              //              } else {
              //                resultMap.put(x._1, dateTime + "|" + dateTime)
              //              }
            } /*else {
              //当定位数据已经超过24小时未上线时，判断是否有登签数据
              val driverSignInfo = jedis.usingRedis { r =>
                r.select(9)
                r.hget("driverSign:" + x._1, "time")
              }
              if (StringUtils.isNotEmpty(driverSignInfo)) {
                val driverSignDateTime = driverSignInfo.split("\\|")
                val driverSignTime = DateTime.parse(driverSignDateTime(0), formatter)
                val driverSignMinutes = Minutes.minutesBetween(driverSignTime, detectionTime).getMinutes
                if (driverSignMinutes < 1440) {
                  equipmentWarnType = 1
                  resultMap.put(x._1, splits(0) + "|" + dateTime)
                }
              }
            }*/
          } /*else {
            //当定位数据没有时，判断是否有登签数据
            val driverSignInfo = jedis.usingRedis { r =>
              r.select(9)
              r.hget("driverSign:" + x._1, "time")
            }
            if (StringUtils.isNotEmpty(driverSignInfo)) {
              val driverSignDateTime = driverSignInfo.split("\\|")
              val driverSignTime = DateTime.parse(driverSignDateTime(0), formatter)
              val driverSignMinutes = Minutes.minutesBetween(driverSignTime, detectionTime).getMinutes
              if (driverSignMinutes < 1440) {
                equipmentWarnType = 1
                resultMap.put(x._1, splits(0) + "|" + dateTime)
              }
            }

          }*/
        }

        (x._1, equipmentWarnType, splits(0))
      }
      smartMap.filter(x => x._2 != 0)
        .foreach { x =>
          val warnTypeCode = warnCode
          val warnTypeNameOption = baseWarn.get(warnTypeCode)
          warnTypeNameOption.foreach { warnTypeName =>
            jedis.usingRedis { r =>
              r.select(9)
              val driverInfo: util.Map[String, String] = r.hgetAll("driverInfo:" + x._1)
              //驾驶员姓名
              val driverName = driverInfo.get("driverName")
              //驾驶员编码
              val driverCode = driverInfo.get("driverCode")
              //车辆所属公司编码
              val vehicleEnterpriseCode = driverInfo.get("vehicleEnterprise")
              //车辆使用性质
              val useNature = driverInfo.get("useNature")
              //车辆管控类型
              val controlType = driverInfo.get("controlType")

              val vehInfo = x._1.split("#")
              val vehicleNo = vehInfo(0)
              val vehicleColor = vehInfo(1)
              val tempKey = x._1 + "_" + warnTypeCode + "_"
              val warnDateTime = riskMillis / 1000
              val primaryKey = tempKey + riskMillis
              val id = tempKey + warnDateTime
              val warnMap = new java.util.HashMap[String, String]()
              warnMap.put("id", id)
              warnMap.put("primaryKey", primaryKey)
              warnMap.put("districtCode", "-")
              warnMap.put("infoId", "-")
              warnMap.put("warnType", "-")
              warnMap.put("eventType", "-")
              warnMap.put("typeName", warnTypeName)
              warnMap.put("typeCode", warnTypeCode)
              warnMap.put("deviceId", "-")
              warnMap.put("speed", "-")
              warnMap.put("datetime", warnDateTime.toString)
              warnMap.put("riskCodeTime", getRiskCodeTime(riskMillis))
              warnMap.put("levelId", RiskConst.WARNING_LEVEL_FIRST)
              warnMap.put("warnSrc", RiskConst.WARNING_SOURCE)
              warnMap.put("warnSeq", "0")
              warnMap.put("longitude", "-")
              warnMap.put("latitude", "-")
              warnMap.put("lastLoginTime", x._3)
              warnMap.put("driverName", driverName)
              warnMap.put("driverCode", driverCode)
              warnMap.put("vehicleEnterpriseCode", vehicleEnterpriseCode)
              warnMap.put("vehicleNo", vehicleNo)
              warnMap.put("vehicleColor", vehicleColor)
              warnList += ((id, MapToJson.Map2Josn(warnMap)))
              //更新当前周期的报警id和时间及驾驶时长
              val evidenceKey = "riskTimes:" + x._1 + "_" + warnDay
              val evidence = AlarmEvidence(id, warnDateTime.toString, 0)
              PeriodProcess.updatePeriodWarnTimes(evidenceKey, warnTypeCode, evidence, r, true)
              val currentCar: util.Map[String, String] = r.hgetAll(evidenceKey)
              riskTimeList += (AlarmNumber(currentCar, vehicleNo, vehicleColor, "0", "-", "-", riskMillis.toString, useNature, controlType, warnDay, List(warnTypeCode)))
            }
          }
        }

      if (MapUtils.isNotEmpty(resultMap)) {
        jedis.usingRedis { r =>
          r.select(9)
          r.hmset(key, resultMap)
        }
      }

    }
  }


  /**
   * GPS设备上线异常和智能设备上线异常处理三天未上线异常报警（普货/危货/客运/出租车）
   *
   * @param key
   * @param dateTime
   * @param smartDatas
   * @param gpsDatas
   * @param baseWarn
   * @param warnCode
   * @param jedis
   * @param warnList
   * @param riskTimeList
   */
  def online3DayAbnormalAlarm(key: String,
                              dateTime: String,
                              smartDatas: util.Map[String, String],
                              gpsDatas: util.Map[String, String],
                              baseWarn: Map[String, String],
                              warnCode: String,
                              jedis: RedisSink,
                              warnList: ListBuffer[(String, String)],
                              riskTimeList: ListBuffer[AlarmNumber]): Unit = {
    val formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
    val format = FastDateFormat.getInstance("yyyyMMdd")
    //    //
    //    val vehScheduleInfo: util.HashMap[String, String] = getVehScheduleInfo()
    //检测时间
    val detectionTime = DateTime.parse(dateTime, formatter)
    //风险触发时间
    val riskMillis = detectionTime.getMillis
    val warnDay = format.format(riskMillis)
    if (MapUtils.isNotEmpty(smartDatas)) {
      //更新的信息
      val resultMap = new util.HashMap[String, String]()
      //报警list
      val smartMap = smartDatas.asScala.map { x =>
        val splits = x._2.split("\\|")
        var minutes = 0
        try {
          val lastOnlineSmartTime = DateTime.parse(splits(0), formatter)
          //智能设备最后上线时间和当前检测时间差
          minutes = Minutes.minutesBetween(lastOnlineSmartTime, detectionTime).getMinutes
        } catch {
          case e: Exception => {
            error(s"设备最后上线时间格式不对:${splits(0)}")
          }
        }

        var equipmentWarnMinutes = 0
        if (2 == splits.size) {
          val lastWarnTimeDay = DateTime.parse(splits(1), formatter)
          //获取智能设备最后上线时间与当前系统时间差：分钟为单位
          equipmentWarnMinutes = Minutes.minutesBetween(lastWarnTimeDay, detectionTime).getMinutes
        }

        var equipmentWarnType = 0
        //智能设备异常报警是否超过三天没有上线
        if ((minutes >= 3 * 1440 && equipmentWarnMinutes == 0) || equipmentWarnMinutes >= 3 * 1440) {
          //判断是否有定位数据
          val gpsData = gpsDatas.get(x._1)
          //          val schedulingState: String = vehScheduleInfo.getOrDefault(x._1,"")
          if (StringUtils.isNotEmpty(gpsData)) {
            val gpsDateTime = gpsData.split("\\|")
            val gpsTime = DateTime.parse(gpsDateTime(0), formatter)
            //获取GPS设备最后上线时间与当前系统时间差：分钟为单位
            val gpsMinutes = Minutes.minutesBetween(gpsTime, detectionTime).getMinutes
            //当GPS设备定位数据小于3天未上线时，判断是否有登签数据
            if (gpsMinutes < 3 * 1440) {
              equipmentWarnType = 1
              resultMap.put(x._1, splits(0) + "|" + dateTime)
            } else {
              //当GPS设备定位数据已经超过3天未上线时，判断是否有登签数据
              val driverSignInfo = jedis.usingRedis { r =>
                r.select(9)
                r.hget("driverSign:" + x._1, "time")
              }
              if (StringUtils.isNotEmpty(driverSignInfo)) {
                val driverSignDateTime = driverSignInfo.split("\\|")
                val driverSignTime = DateTime.parse(driverSignDateTime(0), formatter)
                val driverSignMinutes = Minutes.minutesBetween(driverSignTime, detectionTime).getMinutes
                if (driverSignMinutes < 3 * 1440) {
                  equipmentWarnType = 1
                  resultMap.put(x._1, splits(0) + "|" + dateTime)
                }
              }
            }
          } else {
            //当智能设备定位数据没有时，判断是否有登签数据
            val driverSignInfo = jedis.usingRedis { r =>
              r.select(9)
              r.hget("driverSign:" + x._1, "time")
            }
            if (StringUtils.isNotEmpty(driverSignInfo)) {
              val driverSignDateTime = driverSignInfo.split("\\|")
              val driverSignTime = DateTime.parse(driverSignDateTime(0), formatter)
              val driverSignMinutes = Minutes.minutesBetween(driverSignTime, detectionTime).getMinutes
              if (driverSignMinutes < 3 * 1440) {
                equipmentWarnType = 1
                resultMap.put(x._1, splits(0) + "|" + dateTime)
              }
            }

          }
        }

        (x._1, equipmentWarnType, splits(0))
      }
      smartMap.filter(x => x._2 != 0)
        .foreach { x =>
          val warnTypeCode = warnCode
          val warnTypeNameOption = baseWarn.get(warnTypeCode)
          warnTypeNameOption.foreach { warnTypeName =>
            jedis.usingRedis { r =>
              r.select(9)
              val driverInfo: util.Map[String, String] = r.hgetAll("driverInfo:" + x._1)
              //驾驶员姓名
              val driverName = driverInfo.get("driverName")
              //驾驶员编码
              val driverCode = driverInfo.get("driverCode")
              //车辆所属公司编码
              val vehicleEnterpriseCode = driverInfo.get("vehicleEnterprise")
              //车辆使用性质
              val useNature = driverInfo.get("useNature")
              //车辆管控类型
              val controlType = driverInfo.get("controlType")

              val vehInfo = x._1.split("#")
              val vehicleNo = vehInfo(0)
              val vehicleColor = vehInfo(1)
              val tempKey = x._1 + "_" + warnTypeCode + "_"
              val warnDateTime = riskMillis / 1000
              val primaryKey = tempKey + riskMillis
              val id = tempKey + warnDateTime
              val warnMap = new java.util.HashMap[String, String]()
              warnMap.put("id", id)
              warnMap.put("primaryKey", primaryKey)
              warnMap.put("districtCode", "-")
              warnMap.put("infoId", "-")
              warnMap.put("warnType", "-")
              warnMap.put("eventType", "-")
              warnMap.put("typeName", warnTypeName)
              warnMap.put("typeCode", warnTypeCode)
              warnMap.put("deviceId", "-")
              warnMap.put("speed", "-")
              warnMap.put("datetime", warnDateTime.toString)
              warnMap.put("riskCodeTime", getRiskCodeTime(riskMillis))
              warnMap.put("levelId", RiskConst.WARNING_LEVEL_FIRST)
              warnMap.put("warnSrc", RiskConst.WARNING_SOURCE)
              warnMap.put("warnSeq", "0")
              warnMap.put("longitude", "-")
              warnMap.put("latitude", "-")
              warnMap.put("lastLoginTime", x._3)
              warnMap.put("driverName", driverName)
              warnMap.put("driverCode", driverCode)
              warnMap.put("vehicleEnterpriseCode", vehicleEnterpriseCode)
              warnMap.put("vehicleNo", vehicleNo)
              warnMap.put("vehicleColor", vehicleColor)
              warnList += ((id, MapToJson.Map2Josn(warnMap)))
              //更新当前周期的报警id和时间及驾驶时长
              val evidenceKey = "riskTimes:" + x._1 + "_" + warnDay
              val evidence = AlarmEvidence(id, warnDateTime.toString, 0)
              PeriodProcess.updatePeriodWarnTimes(evidenceKey, warnTypeCode, evidence, r, true)
              val currentCar: util.Map[String, String] = r.hgetAll(evidenceKey)
              riskTimeList += (AlarmNumber(currentCar, vehicleNo, vehicleColor, "0", "-", "-", riskMillis.toString, useNature, controlType, warnDay, List(warnTypeCode)))
            }
          }
        }

      if (MapUtils.isNotEmpty(resultMap)) {
        jedis.usingRedis { r =>
          r.select(9)
          r.hmset(key, resultMap)
        }
      }

    }
  }


  /**
   * 获取风险发生时间 生成主键用
   *
   * @return
   */
  def getRiskCodeTime(time: Long): String = {
    val format = FastDateFormat.getInstance("yyyyMMdd")
    val day = format.format(time)
    day
  }

  /**
   * @Description 获取车辆排班信息
   * @Date 2021/11/10
   * @Param [plateNum, plateColor]
   * @return scala.Tuple3<java.lang.String,java.lang.String,java.lang.String>
   * */
  def getVehScheduleInfo(): util.HashMap[String, String] = {

    val resultMap = new util.HashMap[String, String]()
    var connection: Connection = null
    var statement: PreparedStatement = null
    var resultSet: ResultSet = null
    try {
      connection = mysqlConn()
      val sql = "select plate_num,plate_color,scheduling_date,scheduling_state from hzcp_itms.base_vehicle_scheduling where scheduling_date = current_date() "
      statement = connection.prepareStatement(sql)
      resultSet = statement.executeQuery()
      while (resultSet.next()) {
        val plateNum: String = resultSet.getString("plate_num") //车牌
        //1 蓝 2 黄 3 黑 4 白 5 绿 6 渐变绿色 9 其他
        var plateColor: String = resultSet.getString("plate_color") //车辆颜色
        plateColor match {
          case "蓝" => plateColor = "1"
          case "黄" => plateColor = "2"
          case "黑" => plateColor = "3"
          case "白" => plateColor = "4"
          case "绿" => plateColor = "5"
          case "渐变绿色" => plateColor = "6"
          case _ => plateColor = "9"
        }
        val schedulingState: String = resultSet.getString("scheduling_state") //排班状态
        val vehNum = plateNum + "#" + plateColor
        resultMap.put(vehNum, schedulingState)
      }
    } catch {
      case e => e.printStackTrace
    } finally {

      try {
        CommonUtils.autoCloseable(resultSet, statement, connection)
      } catch {
        case e => logger.error("关闭连接失败！")
      }
    }

    resultMap
  }
}
